﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Albatross.WPF.Common.PubSub {
	public interface IPublisher {
		/// <summary>
		/// Publish an event.
		/// </summary>
		/// <param name="sender">the sender of the event</param>
		/// <param name="topic">the topic of the event</param>
		/// <param name="msg">the message of the event</param>
		void Publish(object sender, string topic, object msg);

		/// <summary>
		/// Subscribe to event topic for message type T using the default subscription class Subscription&lt;T&gt;.  
		/// The function returns a ISubscription&lt;T&gt; object that can be used by the subscriber.  Please note that 
		/// in general the ISubscription object needs to be disposed when no longer needed.
		/// </summary>
		/// <typeparam name="T">The type of message</typeparam>
		/// <param name="subscriber">The subscriber object</param>
		/// <param name="topic">The event topic</param>
		/// <returns>A newly created and registered ISubscription&lt;T&gt; object</returns>
		ISubscription<T> Subscribe<T>(object subscriber, string topic, MsgReceivedEventHandler<T> handler);

		/// <summary>
		/// Subscribe to event topic for message type T using the subscription class S.  The function returns a ISubscription&lt;T&gt; object
		/// that can be used by the subscriber.  Please note that in general the ISubscription object needs to be disposed when no longer needed.
		/// </summary>
		/// <typeparam name="T">The type of message</typeparam>
		/// <typeparam name="S">The type of the subscription class.  The class S should implement ISubscription&lt;T&gt;></typeparam>
		/// <param name="subscriber">The subscriber object</param>
		/// <param name="topic">The event topic</param>
		/// <returns>A newly created and registered ISubscription&lt;T&gt; object</returns>
		ISubscription<T> Subscribe<T, S>(object subscriber, string topic) where S : ISubscription<T>, new();

		/// <summary>
		/// Unsubscribe a certain subscription.  Reference equal are used to check if the subscription belong to the publisher.  Therefore only
		/// subscription objects created by the publisher will be unsubscribed.
		/// </summary>
		/// <param name="sub">The subscription object.</param>
		void Unsubscribe(ISubscription sub);

		/// <summary>
		/// Unsubscribe all subscriptions from a single subscriber
		/// </summary>
		/// <param name="subscriber">The subscriber object.</param>
		void UnsubscribeAll(object subscriber);

		/// <summary>
		/// Clear all subscriptions
		/// </summary>
		void Clear();
	}
}
